//文件名：VehicleOtaMain
//功能：整车OTA函数功能实现
//创建时间：2023年3月9日
//作者：dowson
//email：dowson.tseng@gmail.com

//#include "system_init.h"
#include "4G-HTTP_open_GPS.h"
#include "JuzhenJson.h"
#include "OtaData.h"
#include "OtaDataJson.h"
#include "TigerTallyLock.h"
#include "OtaArrayQueueMng.h"
#include "Mqtt4GDriver.h"
#include "VehicleOta.h"
#include "stdlib.h"
#include "at32f403a_407_board.h"

extern t_OtaStateManage OtaStateManage; //用于管理当前升级对象
extern t_VehicleOtaPkg VehicleOtaPkg;  //包含全部升级零部件内容
extern t_TigerTallyLock TigerTallyLockEcu; //用于管理升级顺序步骤
extern t_otaMsgMark otaMsgMark;


extern t_otaPushMsg otaCmdMsgPkg;
extern t_otaParamPushMsg otaEcuParamMsgPkg;
extern t_otaCmdAck otaMsgAckPkg;      

static int8_t CreatOtaMsgQueueData(tOtaEcuData *OtaEcuData,t_otaParamData *otaParamData);

//检查该消息是否为升级包数据
static UPGRADE_MSG_TYPE IsOtaPkg(uint8_t* dataBuff,uint16_t dataLen){
    if(strstr((const char*)dataBuff,"ota_cmd")){
        return OTA_CMD_MSG;
    }else if(strstr((const char*)dataBuff,"ota_param")){
        return OTA_PARAM_MSG;
    }
    return OTA_UNKNOWN_MSG;
}
//升级信息数据管理初始化函数
void OtaMsgMarkDataInit(t_otaMsgMark *otaMsgMark){
    otaMsgMark->ecuCount = 0;
    otaMsgMark->ecuMsgMark = 0;
    otaMsgMark->ecuMsgReciveCount = 0;
    otaMsgMark->ticksSec = 0;
    otaMsgMark->haveOtaCmd = false;

    memset(&otaEcuParamMsgPkg,0x00,sizeof(t_otaParamPushMsg));
    otaEcuParamMsgPkg.data.pF.slice = 0;
    otaEcuParamMsgPkg.data.dF.slice = 0;
    otaEcuParamMsgPkg.data.oF.slice = 0;

    otaMsgAckPkg.ackHead.unixTime = 0;
    otaMsgAckPkg.ackHead.taskId = 0;
    memset(otaMsgAckPkg.ackHead.nId,0x00,sizeof(otaMsgAckPkg.ackHead.nId));
    memset(otaMsgAckPkg.ackHead.mId,0x00,sizeof(otaMsgAckPkg.ackHead.nId));
    memset(otaMsgAckPkg.ackHead.mType,0x00,sizeof(otaMsgAckPkg.ackHead.mType));
    memset(otaMsgAckPkg.data.descrbtion,0x00,sizeof(otaMsgAckPkg.data.descrbtion));
    memset(otaMsgAckPkg.data.request,0x00,sizeof(otaMsgAckPkg.data.request));
    otaMsgAckPkg.data.state = 0;
    otaMsgAckPkg.data.taskId = 0;

}

//获得订阅节点
//返回 -1 缓存内存溢出,-2 vin 无效,type 0表示接收  1表示推送
int8_t OtaMqttGetTopic(char *topicBuff,uint8_t topicBuffLen,tMqttMsgType type){
    extern tSystemState SystemState;
#if VIN_TEST
    uint8_t* subTopic = "server-dev/";
    uint8_t *pushTopic = "vehicle-dev/";
#else
    uint8_t* subTopic = "server-";
    uint8_t *pushTopic = "vehicle-";
#endif
    uint8_t *fatherTopic = NULL;
    if(MQTT_PUBLISH == type){
        fatherTopic = pushTopic;
    }else{
        fatherTopic = subTopic;
    }
    if(strlen((const char*)fatherTopic)+17+4>topicBuffLen)
        return -1;
    memset(topicBuff,0x00,topicBuffLen);
    //TODO:可能会出现VIN号错误的情况，这里必须有提示
    strcat(topicBuff,(const char*)fatherTopic);

#if VIN_TEST
    strcat((char*)topicBuff,(const char*)SystemState.Vin);
#else
    SetVinState(GetVehicleVin(SystemState.Vin)==0?1:0);
    
    if(GetVinState()){
        fprintf(USART2_STREAM,"get vin:%s\r\n",SystemState.Vin);
        strcat(topicBuff,"pro/");
    }else{
        strcat(topicBuff,"dev/");
        if(SystemState.Vin[0] != 0xff)
        {
            fprintf(USART2_STREAM,"use SN vin\r\n");
        }else{
            fprintf(USART2_STREAM,"no vin\r\n");
            return -2;
        }
    } 
    strcat(topicBuff, (char *)SystemState.Vin);
#endif
    return 0;
}

//ota上传数据结构体初始化
void OtaCmdMsgAckPkgInit(t_otaCmdAck *otaMsgAckPkg){
    memset(otaMsgAckPkg->ackHead.mType,0x00,sizeof(otaMsgAckPkg->ackHead.mType));
    memset(otaMsgAckPkg->ackHead.mId,0x00,sizeof(otaMsgAckPkg->ackHead.mId));
    memset(otaMsgAckPkg->ackHead.nId,0x00,sizeof(otaMsgAckPkg->ackHead.nId));
    otaMsgAckPkg->data.state = false;
    memset(otaMsgAckPkg->data.request,0x00,sizeof(otaMsgAckPkg->data.request));
    memset(otaMsgAckPkg->data.descrbtion,0x00,sizeof(otaMsgAckPkg->data.descrbtion));
    memset(otaMsgAckPkg->data.hv,0x00,sizeof(otaMsgAckPkg->data.hv));
    memset(otaMsgAckPkg->data.sv,0x00,sizeof(otaMsgAckPkg->data.sv));
}


//ota推送信息回传函数
int8_t OtaServerMsgAck(uint8_t mqtt_id,uint8_t jsonTypeGEN_OtaId,bool state,uint32_t taskId,uint8_t *msgType,uint8_t *request,uint8_t *descrbtion){
    extern tSystemState SystemState;
    char topic[64];
    uint8_t sendDataBuff[1024];
    memset(sendDataBuff,0x00,sizeof(sendDataBuff));
    OtaCmdMsgAckPkgInit(&otaMsgAckPkg);
    if(OtaMqttGetTopic(topic,sizeof(topic),MQTT_PUBLISH)){
        fprintf(USART2_STREAM,"--get topic error\r\n");
        return -1;
    }
    memcpy(otaMsgAckPkg.ackHead.mType,msgType,strlen((const char*)msgType));
    memcpy(otaMsgAckPkg.ackHead.mId,SystemState.Vin,strlen((const char*)(SystemState.Vin)));
    memcpy(otaMsgAckPkg.ackHead.nId,SystemState.Vin,strlen((const char*)(SystemState.Vin)));
    otaMsgAckPkg.ackHead.taskId = taskId;
    otaMsgAckPkg.ackHead.unixTime = 1681732512;
    memcpy(otaMsgAckPkg.data.request,request,strlen((const char*)request));
    memcpy(otaMsgAckPkg.data.descrbtion,descrbtion,strlen((const char*)descrbtion));
    otaMsgAckPkg.data.state = state;
    //生成json
    JuzhenJson_GenById(jsonTypeGEN_OtaId,(char* const)sendDataBuff,sizeof(sendDataBuff));
    fprintf(USART2_STREAM,"--push cmd ack msg\r\n");
    MqttPub(mqtt_id,0,0,0,(uint8_t *)topic,strlen((const char*)sendDataBuff),sendDataBuff);
    GOToSleep(TASK_AT_WAIT);
    return 0;
}

//ota推送信息回传函数
int8_t OtaSubOlineMsgUp(uint8_t mqtt_id,uint8_t jsonTypeGEN_OtaId,uint8_t *msgType){
    printf("OtaSubOlineMsgUp-entter...\r\n");
    extern tSystemState SystemState;
    char topic[64];
    int jsonGenRes = -1;
    uint8_t sendDataBuff[1024];
    memset(sendDataBuff,0x00,sizeof(sendDataBuff));
    OtaCmdMsgAckPkgInit(&otaMsgAckPkg);

    if(OtaMqttGetTopic(topic,sizeof(topic),MQTT_PUBLISH)){
        fprintf(USART2_STREAM,"--get topic error\r\n");
        return -1;
    }
    memcpy(otaMsgAckPkg.ackHead.mType,msgType,strlen((const char*)msgType));
    memcpy(otaMsgAckPkg.ackHead.mId,SystemState.Vin,strlen((const char*)(SystemState.Vin)));
    memcpy(otaMsgAckPkg.ackHead.nId,SystemState.Vin,strlen((const char*)(SystemState.Vin)));
    strcpy((char*)(otaMsgAckPkg.data.request),"online");
    otaMsgAckPkg.ackHead.unixTime = 1681732512;
    //生成json
    jsonGenRes = JuzhenJson_GenById(jsonTypeGEN_OtaId,(char* const)sendDataBuff,sizeof(sendDataBuff));
    printf("OtaSubOlineMsgUp-jsonGenRes:%d\r\n", jsonGenRes);
    printf("OtaSubOlineMsgUp-sendDataBuf:%s, length:%d\r\n", sendDataBuff, strlen((const char*)sendDataBuff));
    MqttPub(mqtt_id,0,0,0,(uint8_t *)topic,strlen((const char*)sendDataBuff),sendDataBuff);
    GOToSleep(TASK_AT_WAIT);
    return 0;
}



int8_t OtaUpgradeMsgAck(uint8_t mqtt_id,uint8_t jsonTypeGEN_OtaId,bool state,uint8_t *msgType,uint8_t *request,uint8_t *descrbtion){
    extern tSystemState SystemState;
    char topic[64];
    uint8_t sendDataBuff[1024];
    memset(sendDataBuff,0x00,sizeof(sendDataBuff));
    OtaCmdMsgAckPkgInit(&otaMsgAckPkg);


    if(OtaMqttGetTopic(topic,sizeof(topic),MQTT_PUBLISH)){
        return -1;
    }
    memcpy(otaMsgAckPkg.ackHead.mType,msgType,strlen((const char*)msgType));
    memcpy(otaMsgAckPkg.ackHead.mId,SystemState.Vin,strlen((const char*)(SystemState.Vin)));
    memcpy(otaMsgAckPkg.ackHead.nId,SystemState.Vin,strlen((const char*)(SystemState.Vin)));
    otaMsgAckPkg.ackHead.unixTime = 1681732512;
    memcpy(otaMsgAckPkg.data.request,request,strlen((const char*)request));
    memcpy(otaMsgAckPkg.data.descrbtion,descrbtion,strlen((const char*)descrbtion));
    otaMsgAckPkg.data.state = state;

    strcpy((char*)(otaMsgAckPkg.data.hv),"hta01");
    strcpy((char*)(otaMsgAckPkg.data.sv),"sta01");
    //生成json
    JuzhenJson_GenById(jsonTypeGEN_OtaId,(char *const)sendDataBuff,sizeof(sendDataBuff));
    MqttPub(mqtt_id,0,0,0,(uint8_t *)topic,strlen((const char*)sendDataBuff),sendDataBuff);
    GOToSleep(TASK_AT_WAIT);
    return 0;
}

// //ota下载，升级完成信息上报函数
// int8_t OtaUpgradeOrDownloadStateUp(uint8_t mqtt_id,uint8_t jsonTypeGEN_OtaId,uint8_t *msgType){
//     extern tSystemState SystemState;
//     uint8_t topic[64];
//     uint8_t sendDataBuff[1024];
//     memset(sendDataBuff,0x00,sizeof(sendDataBuff));
//     OtaMqttGetTopic(topic,sizeof(topic));
//     memcpy(otaDownloadStateUpPkg.mType,"msgType",strlen(msgType));
//     memcpy(otaDownloadStateUpPkg.mId,SystemState.Vin,strlen(SystemState.Vin));
//     memcpy(otaDownloadStateUpPkg.nId,SystemState.Vin,strlen(SystemState.Vin));
//     otaDownloadStateUpPkg.unixTime = 1681732512;


//     //生成json
//     JuzhenJson_GenById(jsonTypeGEN_OtaId,sendDataBuff,sizeof(sendDataBuff));
//     MqttPubAscii(mqtt_id,topic,0,0,0,strlen(sendDataBuff),sendDataBuff);    
// }

//挡位字符串转标准型
static int8_t VechileOtaGear2Int(uint8_t *_DstGear,uint8_t _SrcGear){
    switch (_SrcGear)
    {
    case 'N':
        *_DstGear = 0x00;
        break;
    case 'D':
        *_DstGear = 0x0E;
        break;
    case 'R':
        *_DstGear = 0x0D;
        break;
    case 'P':
        *_DstGear = 0x0F;
        break;
    default:
        *_DstGear = 0xff;
        break;
    }
    return 0;
}

//升级消息处理
void CheckVehicleOtaMsgCallBack(uint8_t* dataBuff,uint16_t dataLen){
    printf("CheckVehicleOtaMsgCallBack-dataBuff:%s, dataLen:%d\r\n", dataBuff, dataLen);
    extern tSystemState SystemState;
    uint16_t i=0;
    // uint8_t dataOK=0;
    uint8_t threadState=0;
    tOtaEcuData OtaEcuData;
    uint8_t ret=0;
    extern t_otaMsgMark otaMsgMark;
    // uint8_t mqtt_id=1;
    uint8_t sendDataBuff[1024];
    memset(sendDataBuff,0x00,sizeof(sendDataBuff));
    // uint8_t* fatherTopic = "TID-test-dev/";
    ret = JuzhenJson_Parse((const char*)dataBuff,dataLen);
    fprintf(USART2_STREAM,"--out JuzhenJson_Parse,ret is:%d\r\n",ret);
    ret = IsOtaPkg(dataBuff,dataLen);
    // ret = OTA_CMD_MSG;
    Wirelesess_ReceiveBuff_Eliminate();
    fprintf(USART2_STREAM,"--out IsOtaPkg,ret is:%d\r\n",ret);
    switch(ret){
        case OTA_CMD_MSG:
            //创建接收超时检测与相应回传任务，创建ota升级数据记录结构体
            if(!otaMsgMark.haveOtaCmd){
                otaMsgMark.haveOtaCmd = true;
                otaMsgAckPkg.ackHead.taskId = otaCmdMsgPkg.data.taskId;
                //返回应答消息
                fprintf(USART2_STREAM,"--task id is:%d\r\n",otaCmdMsgPkg.data.taskId);
                fprintf(USART2_STREAM,"--ecuCount:%d\r\n",otaCmdMsgPkg.data.ecuCount);
                fprintf(USART2_STREAM,"--chgSta:%d\r\n",otaCmdMsgPkg.data.otaPushCondition.chgSta);
                fprintf(USART2_STREAM,"--forceSta:%d\r\n",otaCmdMsgPkg.data.otaPushCondition.forceSta);
                fprintf(USART2_STREAM,"--gear:%s\r\n",otaCmdMsgPkg.data.otaPushCondition.gear);
                fprintf(USART2_STREAM,"--minSOC:%d\r\n",otaCmdMsgPkg.data.otaPushCondition.minSOC);
                fprintf(USART2_STREAM,"--minVolt:%d\r\n",otaCmdMsgPkg.data.otaPushCondition.minVolt);
                fprintf(USART2_STREAM,"--powerSta:%d\r\n",otaCmdMsgPkg.data.otaPushCondition.powerSta);
                fprintf(USART2_STREAM,"--speed:%d\r\n",otaCmdMsgPkg.data.otaPushCondition.speed);
                fprintf(USART2_STREAM,"--velSta:%d\r\n",otaCmdMsgPkg.data.otaPushCondition.velSta);
                //TODO:判定前置条件是否满足
                VehicleOtaPkg.OtaCondition.chargeState = otaCmdMsgPkg.data.otaPushCondition.chgSta;
                VehicleOtaPkg.OtaCondition.forceState = otaCmdMsgPkg.data.otaPushCondition.forceSta;
                VechileOtaGear2Int(&VehicleOtaPkg.OtaCondition.gear,otaCmdMsgPkg.data.otaPushCondition.gear[0]);
                VehicleOtaPkg.OtaCondition.minimumSOC = otaCmdMsgPkg.data.otaPushCondition.minSOC;
                VehicleOtaPkg.OtaCondition.minimumVolt = otaCmdMsgPkg.data.otaPushCondition.minVolt;
                VehicleOtaPkg.OtaCondition.powerState = otaCmdMsgPkg.data.otaPushCondition.powerSta;
                VehicleOtaPkg.OtaCondition.speed = otaCmdMsgPkg.data.otaPushCondition.speed;
                VehicleOtaPkg.OtaCondition.vehcileState = otaCmdMsgPkg.data.otaPushCondition.velSta;
                //装载数据
                OtaServerMsgAck(1,RTE_GEN_OTA_CMD_ACK_ID,true,otaCmdMsgPkg.data.taskId,"ota_up","answer_push","ok");
                threadState = ThirdHasBeenCreat(VehicleOtaCmdAckMain);
                if (threadState==0x01){
                    CreatThird("OtaCA",To_OS_Slice_Time(1,OS_SEC),10,VehicleOtaCmdAckMain);
                }
                otaMsgMark.ecuCount = otaCmdMsgPkg.data.ecuCount;
            }else{
                //已经收到控制指令，按情况选择不接受处理
            }
        break;
        case OTA_PARAM_MSG:
            fprintf(USART2_STREAM,"--this is ota param msg\r\n");
            fprintf(USART2_STREAM,"--param ota data******\r\n");
            OtaServerMsgAck(1,RTE_GEN_OTA_CMD_ACK_ID,true,otaCmdMsgPkg.data.taskId,"ota_up","answer_param","ok");
            fprintf(USART2_STREAM,"   --param-companyCode:%s\r\n",otaEcuParamMsgPkg.data.Pm.cid);
            fprintf(USART2_STREAM,"   --param-deviceId:%s\r\n",otaEcuParamMsgPkg.data.Pm.did);
            fprintf(USART2_STREAM,"   --param-hardV:%s\r\n",otaEcuParamMsgPkg.data.Pm.hv);
            fprintf(USART2_STREAM,"   --param-softV:%s\r\n",otaEcuParamMsgPkg.data.Pm.sv);
            fprintf(USART2_STREAM,"   --param-targetDevice:%s\r\n",otaEcuParamMsgPkg.data.Pm.ecu);
            fprintf(USART2_STREAM,"   --data-index:%d\r\n",otaEcuParamMsgPkg.data.Pm.index);
            fprintf(USART2_STREAM,"--driver ota data******\r\n");
            fprintf(USART2_STREAM,"   ---url:%s\r\n",otaEcuParamMsgPkg.data.dF.url);
            fprintf(USART2_STREAM,"   ---md5:%s\r\n",otaEcuParamMsgPkg.data.dF.md5);
            fprintf(USART2_STREAM,"   ---size:%d\r\n",otaEcuParamMsgPkg.data.dF.size);
            fprintf(USART2_STREAM,"   ---slice:%d\r\n",otaEcuParamMsgPkg.data.dF.slice);
            for ( i = 0; i < 10; i++)
                fprintf(USART2_STREAM,"   ---ssize[%d]:%d\r\n",i,otaEcuParamMsgPkg.data.dF.ssize[i]);
            fprintf(USART2_STREAM,"--ota ota data******\r\n");
            fprintf(USART2_STREAM,"   ---url:%s\r\n",otaEcuParamMsgPkg.data.oF.url);
            fprintf(USART2_STREAM,"   ---md5:%s\r\n",otaEcuParamMsgPkg.data.oF.md5);
            fprintf(USART2_STREAM,"   ---size:%d\r\n",otaEcuParamMsgPkg.data.oF.size);
            fprintf(USART2_STREAM,"   ---slice:%d\r\n",otaEcuParamMsgPkg.data.oF.slice);


            for ( i = 0; i < 10; i++)
                fprintf(USART2_STREAM,"   ---ssize[%d]:%d\r\n",i,otaEcuParamMsgPkg.data.oF.ssize[i]);
            //生成升级资料
            CreatOtaMsgQueueData(&OtaEcuData,&otaEcuParamMsgPkg.data);
            OtaQueueMngPut(&OtaEcuData); //加入升级队列
            otaMsgMark.ecuMsgReciveCount++;
            otaMsgMark.ticksSec = 0;
        break;
        default:
            fprintf(USART2_STREAM,"--unknow command\r\n");
        break;
    }
    fprintf(USART2_STREAM,"mqtt--out CheckVehicleOtaMsgCallBack,ecuMsgReciveCount:%d\r\n",otaMsgMark.ecuMsgReciveCount);
}
//升级结束统一处理函数
void OtaUpgradeEndHandle(uint8_t otaState){
    otaMsgMark.haveOtaCmd = false;
}


//通过URL获得文件类型
OtaFileType OtaFromUrlGetFileType(uint8_t *url,uint16_t urlLen){
    // uint8_t *head = url+urlLen;
    // uint16_t i=0,j=0;
    if(strstr((const char*)url,".s19\0")) return OTA_FILE_S19;
    else if(strstr((const char*)url,".S19\0")) return OTA_FILE_S19;
    else if(strstr((const char*)url,".bin\0")) return OTA_FILE_BIN;
    else if(strstr((const char*)url,".hex\0")) return OTA_FILE_HEX;
    else if(strstr((const char*)url,".aff\0")) return OTA_FILE_AFF;
    else return OTA_FILE_UNKNOW_TYPE;  
}
//从URL中获得父连接
int8_t OtaFromUrlGetFatherUrl(uint8_t *url,uint16_t urlLen,uint8_t *fatherUrlBuff,uint16_t fatherUrlBuffLen){
    uint16_t i=0;
    uint8_t urlCpy[FURL_LEN_MAX];
    uint8_t *str_ptr;
    memcpy(urlCpy,url,FURL_LEN_MAX);
    fprintf(USART2_STREAM,"--source url is:%s\r\n",urlCpy);
    for (i = 0; i < urlLen; i++){
        if(0x2f == urlCpy[i]){
            str_ptr = &urlCpy[i];
        }
    }
    fprintf(USART2_STREAM,"--sub url is:%s\r\n",urlCpy);
    if(strlen((const char*)urlCpy)<fatherUrlBuffLen){
        str_ptr++;
        *str_ptr = 0;
        strcpy((char*)fatherUrlBuff,(const char*)urlCpy);
        return 0;
    }else{
        return -2;
    }
}

//初始化
void OtaInitFileDataBuff(tOtaFileData *fileDataBuff){
    memset(fileDataBuff->md5Code,0x00,MD5_LEN_MAX);
    fileDataBuff->fileType = OTA_FILE_UNKNOW_TYPE;
    fileDataBuff->fatherLinkLen = 0;
    fileDataBuff->fileSizeSum = 0;
    memset(fileDataBuff->fatherUrl,0x00,FURL_LEN_MAX);
    memset(fileDataBuff->fileName,0x00,OTA_ECU_FILE_NAME_MAX);
    fileDataBuff->sliceFileCount = 0;
}

//拷贝数据到升级任务管理中
int8_t OtaCopyData(tOtaFileData *Dst_OtaFileData,t_otaFileUrlData *Sor_otaFileUrlData,uint8_t *fileName){
    OtaFileType fileType;
    uint8_t buf[4];
    uint16_t i=0;
    fileType = OtaFromUrlGetFileType(Sor_otaFileUrlData->url,strlen((const char*)(Sor_otaFileUrlData->url)));
    if(fileType){
        Dst_OtaFileData->fileType = fileType;
    }else{
        //返回找不到文件类型
        return -1;
    }
    if(OtaFromUrlGetFatherUrl(Sor_otaFileUrlData->url,strlen((const char*)(Sor_otaFileUrlData->url)),Dst_OtaFileData->fatherUrl,FURL_LEN_MAX)){
        //返回找不到文件url
        return -2;
    }
    Dst_OtaFileData->fatherLinkLen = strlen((const char*)(Dst_OtaFileData->fatherUrl));
    strcpy((char*)(Dst_OtaFileData->fileName),(const char*)fileName);
    Dst_OtaFileData->fileSizeSum = Sor_otaFileUrlData->size;
    Dst_OtaFileData->sliceFileCount = Sor_otaFileUrlData->slice;
    strcpy((char*)(Dst_OtaFileData->md5Code),(const char*)(Sor_otaFileUrlData->md5));
    for(i=0;i<Sor_otaFileUrlData->slice;i++){
        Dst_OtaFileData->Addr[i].fileSize = Sor_otaFileUrlData->ssize[i];
        Dst_OtaFileData->Addr[i].fileIndex = i;
        strcpy((char*)(Dst_OtaFileData->Addr[i].sunUrl),(const char*)fileName);
        //strcat(Dst_OtaFileData->Addr[i].sunUrl,"_");
        memset(buf,0x00,sizeof(buf));
        sprintf((char*)buf,"%d",i+1);
        strcat((char*)(Dst_OtaFileData->Addr[i].sunUrl),(const char*)buf);
        strcat((char*)(Dst_OtaFileData->Addr[i].sunUrl),".");
        switch (fileType)
        {
        case OTA_FILE_BIN:
            strcat((char*)(Dst_OtaFileData->Addr[i].sunUrl),"bin");
            break;
        case OTA_FILE_HEX:
            strcat((char*)(Dst_OtaFileData->Addr[i].sunUrl),"hex");
            break;
        case OTA_FILE_S19:
            strcat((char*)(Dst_OtaFileData->Addr[i].sunUrl),"s19");  
            break;     
        case OTA_FILE_AFF:
            strcat((char*)(Dst_OtaFileData->Addr[i].sunUrl),"aff");
            break;    
        default:
            break;
        }
        Dst_OtaFileData->Addr[i].linkLen = strlen((const char*)(Dst_OtaFileData->Addr[i].sunUrl));
         fprintf(USART2_STREAM,"--Dst_OtaFileData->fileIndex%d:%d\r\n",i,Dst_OtaFileData->Addr[i].fileIndex);
         fprintf(USART2_STREAM,"--Dst_OtaFileData->fileSize%d:%d\r\n",i,Dst_OtaFileData->Addr[i].fileSize);
         fprintf(USART2_STREAM,"--Dst_OtaFileData->linkLen%d:%d\r\n",i,Dst_OtaFileData->Addr[i].linkLen);
         fprintf(USART2_STREAM,"--Dst_OtaFileData->sunUrl%d:%s\r\n",i,Dst_OtaFileData->Addr[i].sunUrl);
    }
    fprintf(USART2_STREAM,"--Dst_OtaFileData->fatherUrl-len%d-:%s\r\n",Dst_OtaFileData->fatherLinkLen,Dst_OtaFileData->fatherUrl);
    fprintf(USART2_STREAM,"--Dst_OtaFileData->fileName:%s\r\n",Dst_OtaFileData->fileName);
    fprintf(USART2_STREAM,"--Dst_OtaFileData->fileSizeSum:%d\r\n",Dst_OtaFileData->fileSizeSum);
    fprintf(USART2_STREAM,"--Dst_OtaFileData->md5Code:%s\r\n",Dst_OtaFileData->md5Code);
    return 0;
}
 


//生成ota生产资料
int8_t CreatOtaMsgQueueData(tOtaEcuData *OtaEcuData,t_otaParamData *otaParamData){
    // uint8_t i=0;
    
    strcpy((char*)(OtaEcuData->OtaParam.companyCode),(const char*)(otaParamData->Pm.cid));
    strcpy((char*)(OtaEcuData->OtaParam.deviceId),(const char*)(otaParamData->Pm.did));
    strcpy((char*)(OtaEcuData->OtaParam.hardV),(const char*)(otaParamData->Pm.hv));
    strcpy((char*)(OtaEcuData->OtaParam.softV),(const char*)(otaParamData->Pm.sv));
    strcpy((char*)OtaEcuData->OtaParam.targetDevice,(const char*)(otaParamData->Pm.ecu));
    //找到父连接中的文件名和类型
     fprintf(USART2_STREAM,"--otaParamData->pF.slice:%d\r\n",otaParamData->pF.slice);
     fprintf(USART2_STREAM,"--otaParamData->dF.slice:%d\r\n",otaParamData->dF.slice);
     fprintf(USART2_STREAM,"--otaParamData->oF.slice:%d\r\n",otaParamData->oF.slice);
    if(0 != otaParamData->pF.slice)
        OtaCopyData(&OtaEcuData->fileData[OTA_PARAM_FILE],&otaParamData->pF,"param");
    else OtaInitFileDataBuff(&OtaEcuData->fileData[OTA_PARAM_FILE]);
    if(0 != otaParamData->dF.slice)
        OtaCopyData(&OtaEcuData->fileData[OTA_DRIVER_FILE],&otaParamData->dF,"driver");
    else OtaInitFileDataBuff(&OtaEcuData->fileData[OTA_DRIVER_FILE]);
    if(0 != otaParamData->oF.slice)
        OtaCopyData(&OtaEcuData->fileData[OTA_OTA_FILE],&otaParamData->oF,"ota");
    else OtaInitFileDataBuff(&OtaEcuData->fileData[OTA_OTA_FILE]);
     fprintf(USART2_STREAM,"--OtaEcuData->fileData->fatherUrl:%s\r\n",OtaEcuData->fileData[2].fatherUrl);
     fprintf(USART2_STREAM,"--OtaEcuData->fileData->fileName:%s\r\n",OtaEcuData->fileData[2].fileName);
     return 0;
}

//ECU类型转换字符串明-数字
OTA_ECU_TYPE OtaConversionEcuType(uint8_t *ecuName,uint8_t strLen){
    if(strstr((const char*)ecuName,"VCU")||strstr((const char*)ecuName,"VCU"))return OTA_VCU;
    if(strstr((const char*)ecuName,"MCU")||strstr((const char*)ecuName,"mcu"))return OTA_MCU;
    if(strstr((const char*)ecuName,"TBOX")||strstr((const char*)ecuName,"tbox")||strstr((const char*)ecuName,"t-box")||strstr((const char*)ecuName,"T-BOX"))return OTA_TBOX;
    if(strstr((const char*)ecuName,"BMS")||strstr((const char*)ecuName,"bms"))return OTA_BMS;
    if(strstr((const char*)ecuName,"BCM")||strstr((const char*)ecuName,"bcm"))return OTA_BCM;
    if(strstr((const char*)ecuName,"OBC")||strstr((const char*)ecuName,"obc"))return OTA_OBC;
    return OTA_UNKNOW;
}

//ECU文件匹配函数
bool OtaIsMappingFile(OTA_ECU_TYPE ecuType,OtaFileType fileTyep){
    switch (ecuType)
    {
    case OTA_VCU:
        if(OTA_FILE_HEX == fileTyep)return true;
        break;
    case OTA_MCU:
        if(OTA_FILE_HEX == fileTyep)return true;
        if(OTA_FILE_AFF == fileTyep)return true;
        break;
    case OTA_OBC:
    case OTA_BCM: 
    case OTA_BMS:
        if(OTA_FILE_S19 == fileTyep)return true;
        break;
    case OTA_TBOX:
        if(OTA_FILE_BIN == fileTyep)return true;
        break;  
    default:
        return false;
        // break;
    }
    return false;
}


int8_t OtaCheckUpgradeCondtion(void){
    uint16_t result = 0;
    uint16_t resultTheory = 0;
    bool gear_N = 0;
    //TODO：检测全部的车辆状态
    extern tVehicleState VehicleState;
    extern tVehicleData VehicleDtata;
    extern tSystemState SystemState;
    gear_N = (VehicleState.gear == 0 || VehicleState.gear == 0x0f)?1:0;

    resultTheory++;
    fprintf(USART2_STREAM,"--ota chargeState:%d-%d\r\n",VehicleState.VechicleChargeState,VehicleOtaPkg.OtaCondition.chargeState);
    if(VehicleState.VechicleChargeState == VehicleOtaPkg.OtaCondition.chargeState){
        result++;
    }else{
        fprintf(USART2_STREAM,"--ota condition-err chargeState\r\n");
    }
    resultTheory++;
    fprintf(USART2_STREAM,"--ota gear:%d-%d\r\n",VehicleOtaPkg.OtaCondition.gear,gear_N);
    if(TRUE == gear_N){
        //挡位强制判断
        result++;
    }else{
        fprintf(USART2_STREAM,"--ota condition-err gear\r\n");
    }
    resultTheory++;
    fprintf(USART2_STREAM,"--ota minimumSOC:%d-%d\r\n",VehicleOtaPkg.OtaCondition.minimumSOC,VehicleState.SOC);
    if(VehicleOtaPkg.OtaCondition.minimumSOC <= VehicleState.SOC){
        result++;
    }else{
        fprintf(USART2_STREAM,"--ota condition-err minimumSOC\r\n");
    }
    resultTheory++;
    fprintf(USART2_STREAM,"--ota minimumVolt:%d-%d\r\n",VehicleOtaPkg.OtaCondition.minimumVolt,VehicleState.storageVolt);

    if(VehicleOtaPkg.OtaCondition.minimumVolt <= VehicleState.storageVolt){
        result++;
    }else{
        fprintf(USART2_STREAM,"--ota condition-err minimumVolt\r\n");
    }
    resultTheory++;
    fprintf(USART2_STREAM,"--ota powerState:%d-%d\r\n",VehicleOtaPkg.OtaCondition.powerState,VehicleState.powerState);

    if(VehicleOtaPkg.OtaCondition.powerState == VehicleState.powerState){
        result++;
    }else{
        fprintf(USART2_STREAM,"--ota condition-err powerState\r\n");
    }
    resultTheory++;
    fprintf(USART2_STREAM,"--ota speed:%d-%d\r\n",VehicleOtaPkg.OtaCondition.speed,VehicleState.vehicleSpeed);

    if(VehicleOtaPkg.OtaCondition.speed <= VehicleState.vehicleSpeed){
        result++;
    }else{
        fprintf(USART2_STREAM,"--ota condition-err speed\r\n");
    }
    resultTheory++;
    fprintf(USART2_STREAM,"--ota vehcileState:%d-%d\r\n",VehicleOtaPkg.OtaCondition.vehcileState,VehicleState.IGSignal);

    if(VehicleOtaPkg.OtaCondition.vehcileState == VehicleState.IGSignal){
        result++;
    }else{
        fprintf(USART2_STREAM,"--ota condition-err vehcileState\r\n");
    }
    if(resultTheory == result)
        return 0;
    else return -1;
}

//MD5比较函数，0表示相同，其他表示不同
uint8_t OTA_Md5CodeCheck(uint8_t *Str1,uint8_t *Str2,uint8_t compareLen){
    uint8_t i = 0;
    for (i = 0; i < compareLen; i++)
    {
        if (Str1[i] != Str2[i])
        {
            return 1;
        }
    }
    return 0;
}

//S19文件解析，获得S19中包含的字节大小
//输入：text 文件中的一段S19数据
uint8_t GetBytesCountFromS19(uint8_t *text,uint8_t textSize){
    return 0;
}

//HEX文件解析，获得HEX中包含的字节大小
//输入：text 文件中的一段HEX数据
uint8_t GetBytesCountFromHEX(uint8_t *text,uint8_t textSize){
    return 0;
}



